package com.asdf.tests;

import java.util.ArrayList;
import java.util.List;
import java.util.Random;

import com.asdf.application.NetServiceSimulator;
import com.asdf.external.INetserviceSimulator;
import com.asdf.external.stubs.VSDT;

/**
 * Wrapper around NetServiceSimulator, providing transparent encryption
 * using VSDT, i.e. method arguments shuld not be encrypted 
 * @author ilia
 */
class NetServiceSimulatorWrapper implements INetserviceSimulator {
	public NetServiceSimulator ns;
	public VSDT vsdt;
	
	/** encrypt string using VSDT */
	String enc(String s) {
		return vsdt.encrypt(s);
	}
	
	boolean isConnected(String username) {
		return ns.getConnectionTime(username) >= 0;
	}

	boolean isConnected(SimpleUser u) {
		return isConnected( u.username);
	}

	public NetServiceSimulatorWrapper()	{
		this(new NetServiceSimulator());
	}
	
	public NetServiceSimulatorWrapper(NetServiceSimulator ns) {
		this.ns = ns;
		this.vsdt = new VSDT();
	}

	@Override
	public boolean init( String airportsFile, String clubsFile)	{
		return ns.init( airportsFile, clubsFile);
	}

	@Override
	public boolean startConnection( String username, String password) {
		return ns.startConnection( enc(username), enc(password));
	}

	@Override
	public boolean startConnection( String username, String password,
			String ccNumber, String ccProvider, int ccExpirationMonth,
			int ccExpirationYear, int ccZIP)
	{
		return ns.startConnection( enc(username), enc(password),
				enc(ccNumber), enc(ccProvider), 
				ccExpirationMonth, ccExpirationYear, ccZIP);
	}
	
	public boolean startConnection(SimpleUser u) {
		return startConnection( u.username, u.password);
	}

	public boolean startConnection(SimpleUser u, SimpleCreditCard c) {
		return startConnection( u.username, u.password, 
				c.number, c.provider, c.expMonth, c.expYear, c.zip);
	}
	
	@Override
	public boolean endConnection( String username, int chargeTime) {
		return ns.endConnection( username, chargeTime);
	}

	public boolean endConnectionAndCheck( SimpleUser u) {
		return endConnectionAndCheck(u, new Random().nextInt(1000));
	}
	public boolean endConnectionAndCheck( SimpleUser u, int chargeTime) {
		return endConnection(u.username, chargeTime) && !isConnected(u);
	}
	public boolean endConnectionAndCheckNot( SimpleUser u) {
		return !endConnection(u.username,  new Random().nextInt(1000)) && !isConnected(u);
	}
	
	@Override
	public String subscribe( String id, String firstName, String lastName,
			String email, String address, boolean aviationClubMember,
			String aviationCompanyName, boolean getNewsLetters,
			String username, String ccNumber, String ccProvider,
			int ccExpirationMonth, int ccExpirationYear, int ccZIP)
	{
		return ns.subscribe( enc(id), enc(firstName), enc(lastName),
				enc(email), enc(address), 
				aviationClubMember, enc(aviationCompanyName), 
				getNewsLetters, enc(username), 
				enc(ccNumber), enc(ccProvider),
				ccExpirationMonth, ccExpirationYear, ccZIP);
	}
	

	@Override
	public String subscribe( String id, String firstName, String lastName,
			String email, String address, boolean aviationClubMember,
			String aviationCompanyName, boolean getNewsLetters, String username)
	{
		return ns.subscribe( enc(id), enc(firstName), enc(lastName),
				enc(email), enc(address), 
				aviationClubMember, enc(aviationCompanyName), 
				getNewsLetters, enc(username));
	}
	
	public boolean subscribe( SimpleUser u, SimpleCreditCard c ) {
		u.password = subscribe( u.id, u.firstName, u.lastName, 
				u.email, u.address, u.isMember, u.club, u.getNewsletter, u.username,
				c.number, c.provider, c.expMonth, c.expYear, c.zip);
		return u.password!=null;
	}

	public boolean subscribe( SimpleUser u ) {
		u.password = subscribe( u.id, u.firstName, u.lastName, 
				u.email, u.address, u.isMember, u.club, u.getNewsletter, u.username);
		return u.password!=null;
	}

	@Override
	public void switchAirport( String id) {
		ns.switchAirport(id);
	}

	public boolean connectAndCheck(SimpleUser u) {
		return startConnection(u) && isConnected(u);
	}

	public boolean connectAndCheck(SimpleUser u, SimpleCreditCard c) {
		return startConnection(u, c) && isConnected(u);
	}

	public boolean connectAndCheckNot(SimpleUser u) {
		return !startConnection(u) && !isConnected(u);
	}

	public boolean connectAndCheckNot(SimpleUser u, SimpleCreditCard c) {
		return !startConnection(u, c) && !isConnected(u);
	}

	
	class endConnectionData {
		String username;
		int duration;
		
		public endConnectionData(SimpleUser u, int duration) {
			username = u.username;
			this.duration = duration;
		}
	}
	
	List<endConnectionData> conns = new ArrayList<endConnectionData>();

	public boolean connectAndCheck(SimpleUser u, int duration) {
		boolean connected = startConnection(u) && isConnected(u);
		if (connected) {
			conns.add( new endConnectionData(u, duration));
		}
		return connected;
	}

	public boolean connectAndCheck(SimpleUser u, SimpleCreditCard c, int duration) {
		boolean connected = startConnection(u, c) && isConnected(u);
		if (connected) {
			conns.add( new endConnectionData(u, duration));
		}
		return connected;
	}

	public boolean endAllConnections() {
		for (endConnectionData c : conns)
			if (!endConnection( c.username, c.duration))
				return false;
		conns.clear();
		return true;
	}
}

